package com.fanrui.code.chess.mahjong;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import com.fanrui.code.chess.AbstractChessGamer;
import com.fanrui.code.chess.ChessGamerManager;
import com.fanrui.code.chess.ChessTableManager;
import com.fanrui.code.chess.mahjong.MahjongIncome.MahjongIncomeInfo;
import com.fanrui.code.chess.mahjong.MahjongRules.CurrencyType;
import com.fanrui.code.chess.mahjong.round.MahjongOperationResponse;
import com.fanrui.code.mahjong.util.Jing;
import com.fanrui.code.mahjong.util.MahjongCardUtil;
import com.fanrui.code.player.Player;
import com.fanrui.code.player.Player.OperationType;
import com.fanrui.code.player.PlayerDao;
import com.fanrui.code.player.PlayerManager;
import com.fanrui.code.util.logger.Stdout;
import com.fanrui.proto.cmd.GamerInMahjongDeskInfo;
import com.fanrui.proto.cmd.HuType;
import com.fanrui.proto.cmd.MahjongGroup;
import com.fanrui.proto.cmd.MahjongGroup.GroupType;
import com.fanrui.proto.cmd.MahjongIncomeResult;
import com.fanrui.proto.cmd.MahjongType;
import com.fanrui.proto.cmd.Operation;
import com.fanrui.proto.cmd.WannengType;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.annotations.Expose;

public abstract class MahjongGamer extends AbstractChessGamer<Mahjong> {

	/**
	 * 玩家出牌次数
	 */
	private int numberOfSendCard;
	
	/**
	 * 是否已经胡牌
	 */
	protected boolean isHu;
	
	/**
	 * 过手胡的番数 如果为null 表示不是过手胡
	 */
	private Integer guoShouHu = null;
	
	/**
	 * 当前收到的通知
	 */
	protected MahjongOperationResponse currendResponse;
	
	/**
	 * 碰杠吃的牌 
	 */
	protected List<MahjongGroup> group = null;
	
	/**
	 * 玩家的精牌个数
	 */
	protected List<Jing> jings = null;
	
	private List<MahjongIncome> incomes;
	
	private List<Mahjong> replesCard = new ArrayList<Mahjong>();
	
	/**
	 * 玩家在房间的位置
	 */
	@Expose
	protected int seatNo;
	
	public MahjongGamer(int ID, long playerID, int tableID, String ip, double x, double y) {
		super(ID, playerID, tableID, ip, x, y);
	}
	
	public AbstractMahjongTable<?> getTable() {
		return ChessTableManager.getInstance().fuzzyQuery(getTableID(), AbstractMahjongTable.class);
	}

	public void clearWaitOperatoion() {
		currendResponse = null;
		waitTime = null;
	}

	public boolean isHu() {
		return isHu;
	}

	public void setHu(boolean isHu) {
		this.isHu = isHu;
	}

	public List<MahjongGroup> getGroup() {
		return group;
	}

	public Integer getGuoShouHu() {
		return guoShouHu;
	}

	public void setGuoShouHu(Integer guoShouHu) {
		this.guoShouHu = guoShouHu;
	}

	public int getNumberOfSendCard() {
		return numberOfSendCard;
	}

	public void setNumberOfSendCard(int numberOfSendCard) {
		this.numberOfSendCard = numberOfSendCard;
	}
	
	public void addSendNumber() {
		this.numberOfSendCard++;
	}
	
	public boolean removeCard(Mahjong card) {
		return handCards.remove(card);
	}
	
	public String getNickName() {
		return playerInfo.getNickName();
	}

	public int getSeatNo() {
		return seatNo;
	}
	
	public void setSeatNo(int seatNo) {
		this.seatNo = seatNo;
	}

	public MahjongOperationResponse getCurrendResponse() {
		return currendResponse;
	}

	public void setCurrendResponse(MahjongOperationResponse currendResponse) {
		this.currendResponse = currendResponse;
	}

	/**
	 * 玩家是否可以操作某张牌
	 * 
	 * @param card
	 * @return boolean
	 */
	public boolean canOperationCard(Mahjong card, boolean isQiang) {
		if(isQiang) {//抢杠只检测能不能胡牌
			if (checkHu(card)) {
				if (!isHu) {
					return true;
				}
			}
		}else {
			if (checkHu(card)) {
				if (!isHu) {
					return true;
				}
			}
			if (MahjongCardUtil.getInstance().getCardNumFromHand(card, handCards) >= 2) {
				return true;
			}
			if(checkChi(card)) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 玩家是否可以操作某张牌（别人出牌的情况）
	 * @param card 操作的牌
	 * @return 可以操作的类型
	 */
	public List<Operation> canOperationCardList(Mahjong card){
		List<Operation> result = new ArrayList<Operation>();
		if(!(getTable().getGameRules() instanceof BaoHuRules)) {//爆胡没有点炮和吃
			if (checkHu(card)) {
				if (!isHu) {
					result.add(Operation.BOOM);
				}
			}
			if(checkChi(card)) {
				result.add(Operation.CHI);
			}
		}
		if (MahjongCardUtil.getInstance().getCardNumFromHand(card, handCards) >= 2) {
			if(getTable().getGameRules().getRoomConfig().getBaoHuPlayStyle().getLess10CannotPeng()) {
				if(handCards.size() >= 10) {
					result.add(Operation.PENG);
				}
			}else {
				result.add(Operation.PENG);
			}
		}
		if (MahjongCardUtil.getInstance().getCardNumFromHand(card, handCards) == 3) {
			result.add(Operation.GANG_M);
		}
		if(result.isEmpty()) {
			return null;
		}
		return result;
	}
	
	/**
	 * 玩家是否可以操作某张牌（别人出牌的情况）
	 * @param card 操作的牌
	 * @return 可以操作的类型
	 */
	public List<Operation> canOperationCardListMySelf(Mahjong card){
		List<Operation> result = new ArrayList<Operation>();
//		if(getTable().getCurrentRound() != null) {
//			if(this.getPlayerID() != getTable().getCurrentRound().getCurrentId())
//				return result;
//		}
		if(card == null && getHandCards().size() % 3 == 1) {//别人出牌响应
			card = getTable().getLastSendCard();
			if(!(getTable().getGameRules() instanceof BaoHuRules)) {//爆胡没有点炮和吃
				if (checkHu(card)) {
					if (!isHu) {
						result.add(Operation.BOOM);
					}
				}
				if(checkChi(card)) {
					result.add(Operation.CHI);
				}
			}
			if (MahjongCardUtil.getInstance().getCardNumFromHand(card, handCards) == 2) {
				if(getTable().getGameRules().getRoomConfig().getBaoHuPlayStyle().getLess10CannotPeng()) {
					if(handCards.size() >= 10) {
						result.add(Operation.PENG);
					}
				}else {
					result.add(Operation.PENG);
				}
			}
			if (MahjongCardUtil.getInstance().getCardNumFromHand(card, handCards) == 3) {
				result.add(Operation.GANG_M);
			}
		}else {//自己摸牌响应
			if (checkHu(card)) {
				if (!isHu) {
					result.add(Operation.ZIMO);
				}
			}
//			if(group != null && !group.isEmpty()) {
//				for(Mahjong mj : handCards) {
//					for (MahjongGroup g : group) {
//						if(g.getType() == MahjongGroup.GroupType.PENG && mj.cardEquals(g.getMjs(0))) {
//							result.add(Operation.GANG_B);
//							break;
//						}
//					}
//				}
//			}
		}
		if(result.isEmpty()) {
			return null;
		}
		return result;
	}
	
	public boolean checkChi(Mahjong card) {
		if(getTable().getGameRules() instanceof BaoHuRules) {
			return false;
		}
		// 只能吃上家的牌
		if(this.getPlayerID() != getTable().getNextExistSeatPlayerId(getTable().getCurrentRound().getCurrentId())) {
			return false;
		}
		if (card.getType() == MahjongType.SAN) {
			/**     4     3     2
			 * 1   4-1  3-1  2-1
			 * 2   4-2  3-2  2-2
			 * 3   4-3  3-3  2-3
			 * 4   4-4  3-4  2-4
			 */
			if(card.getNumber() <= 4) {
				int san = 0;
				int cardNumber = card.getNumber();
				for (int i = 4; i > 1; i--) {
					int number = i - cardNumber;
					if(number <= 0) {
						number--;
					}
					if(MahjongCardUtil.getInstance().getCardNumFromHand(card.getNextN(number), handCards) >= 1) {
						san++;
					}
				}
				if(san >= 2) {
					return true;
				}
			}else {
				/**     4     3    
				 * 5   7-5  6-5
				 * 6   7-6  6-6
				 * 7   7-7  6-7  
				 */
				int san = 0;
				int cardNumber = card.getNumber();
				for (int i = 7; i > 5; i--) {
					int number = i - cardNumber;
					if(number <= 0) {
						number--;
					}
					if(MahjongCardUtil.getInstance().getCardNumFromHand(card.getNextN(number), handCards) >= 1) {
						san++;
					}
				}
				if(san >= 2) {
					return true;
				}
			}
			return false;
		}
		if ((MahjongCardUtil.getInstance().getCardNumFromHand(card.getNext(), handCards) >= 1
				&& MahjongCardUtil.getInstance().getCardNumFromHand(card.getNextN(-1), handCards) >= 1)
				|| (MahjongCardUtil.getInstance().getCardNumFromHand(card.getNextN(-1), handCards) >= 1
						&& MahjongCardUtil.getInstance().getCardNumFromHand(card.getNextN(-2), handCards) >= 1)
				|| (MahjongCardUtil.getInstance().getCardNumFromHand(card.getNext(), handCards) >= 1
						&& MahjongCardUtil.getInstance().getCardNumFromHand(card.getNextN(2), handCards) >= 1)) {
			return true;
		}
		return false;
	}

	/**
	 * 是否能够胡牌
	 * 
	 * @param card
	 * @return boolean
	 */
	public boolean checkHu(Mahjong card) {
		AbstractMahjongTable<?> table = getTable();
		if (!MahjongCardUtil.getInstance().checkHu(card, this, table.getGameRules())) {
			return false;
		}
		// 是否为过手胡
		if (this.getGuoShouHu() != null) {
			if (this.getMult(card) <= this.getGuoShouHu()) {
				return false;
			} else {
				return false;
			}
		}
		return true;
	}

	public void setGuoShouHuAuto(Mahjong card) {
		AbstractMahjongTable<?> table = getTable();
		if (table != null) {
			if (MahjongCardUtil.getInstance().checkHu(card, this, table.getGameRules())) {
				this.guoShouHu = getMult(card);
			} else {
				this.guoShouHu = null;
			}
		}
	}

	/**
	 * 玩家可以胡的番数
	 * 
	 * @return int
	 */
	public int getMult(Mahjong card) {
		List<HuType> huTypes = getCanHuTypeList(card);
		AbstractMahjongTable<?> table = getTable();
		if (table != null) {
			return table.getGameRules().convertMulAndRemoveType(huTypes);
		}
		return 0;
	}
	
	/**
	 * 玩家可以胡的 胡牌类型
	 * 
	 * @return int
	 */
	public List<HuType> getCanHuTypeList(Mahjong huCard) {
		AbstractMahjongTable<?> table = getTable();
		if (table == null) {
			return Collections.emptyList();
		}
		List<Mahjong> hands = MahjongCardUtil.getInstance().clone(getHandCards());
		boolean isHu = MahjongCardUtil.getInstance().checkHu(hands, true, getTable().getGameRules());
		if (isHu) { // 已经胡牌
			return MahjongCardUtil.getInstance().getMult(huCard, this, false, table.isGang(), false);
		} else {
			List<Mahjong> cards;
			if (huCard != null) {
				cards = Arrays.asList(huCard);
			} else {
				cards = MahjongCardUtil.getInstance().getHuCards(handCards, getTable().getGameRules());
			}

			if (cards != null && !cards.isEmpty()) {
				int maxFan = 0;
				List<HuType> result = Collections.emptyList();
				for (Mahjong card : cards) {
					List<HuType> huTypes = MahjongCardUtil.getInstance().getMult(card, this, false, table.isGang(), false);
					int fan = table.getGameRules().convertMulAndRemoveType(huTypes);
					if (fan > maxFan) {
						maxFan = fan;
						result = huTypes;
					}
				}
				return result;
			} else {
				return Collections.emptyList();
			}
		}
	}
	
	public int getCurrentyIncome() {
		AbstractMahjongTable<?> table = getTable();
		if (table != null && table.getGameRules().getCurrencyType() == CurrencyType.Gold) {
			Player player = PlayerManager.getInstance().findOrCreatePlayer(getPlayerID());
			if (player != null) {
				return (int) player.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold);
			} else {
				return (int) playerInfo.getGold();
			}
		}else {
			return (int) getIncome();
		}
	}

	/**
	 * 收到通知
	 * 
	 * @param response
	 *            void
	 */
	public void notifyResponse(MahjongOperationResponse response, int waitTime) {
		if (response.getType() == Operation.TOUCH && response.getOperationId() != getPlayerID()) {
			return;
		}
		currendResponse = response;
		if (waitTime > 0) {
			if (this.waitTime == null) {
				this.waitTime = new AtomicInteger(waitTime);
			} else {
				this.waitTime.set(waitTime);
			}
		}
	}

	public JsonElement toJson() {
		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
		return gson.toJsonTree(this);
	}

	public MahjongIncomeResult toMahjongIncomeResult() {
		MahjongIncomeResult.Builder builder = MahjongIncomeResult.newBuilder();
		builder.setGamer((com.fanrui.proto.cmd.MahjongGamer) toCmd(true));
		int huIncome = 0;
		int jingIncome = 0;
		if (incomes != null) {
			for (MahjongIncome income : incomes) {
				huIncome += income.getIncome();
				builder.addHuKinds(income.toCmd());

			}
		}
		builder.setHuIncome(huIncome);
		if(jings != null) {
			for(Jing jing : jings) {
				jingIncome += jing.getTotal();
				builder.addJingTotal(jing.toCmd());
			}
		}
		builder.setTotalIncome(huIncome+jingIncome);
		return builder.build();
	}

	
	public com.fanrui.proto.cmd.MahjongGamer toCmd(boolean b) {
		com.fanrui.proto.cmd.MahjongGamer.Builder builder = com.fanrui.proto.cmd.MahjongGamer.newBuilder();
		builder.setUserID(getPlayerID());
		if (playerInfo != null) {
			builder.setNickname(playerInfo.getNickName());
			if(playerInfo.getHeadUrl() == null) {
				builder.setHeadIconUrl("");
			}else {
				builder.setHeadIconUrl(playerInfo.getHeadUrl());
			}
			builder.setUserIP(playerInfo.getIp());
			builder.setLocation(playerInfo.getLocation());
			builder.setLatitudeAndLongitude(playerInfo.getLatitudeAndLongitude());
			builder.setGold(playerInfo.getGold());
			builder.setScore((int) playerInfo.getScore());
			builder.setIsOnline(true);
			builder.setFreestyle("coder");
			builder.setSex(playerInfo.isSex());
		}
		builder.setIsPrepare(isReady());
		builder.setIsHosting(getHosting());
		builder.setIsOnline(getAFK());
		GamerInMahjongDeskInfo.Builder deskInfo = GamerInMahjongDeskInfo.newBuilder();
		if (group != null) {
			deskInfo.addAllMjGroups(group);
		}
		AbstractMahjongTable<?> table = getTable();
		builder.setSeatNo(table.getGamerSeatNO(getPlayerID()));
		if (table.getBankID() != null) {
			deskInfo.setIsBanker(table.getBankID() == getPlayerID());
		}
		if (table != null) {
			Collection<Mahjong> sendCards = table.getSendCards(getPlayerID());
			if (sendCards != null) {
				deskInfo.addAllPopMj(MahjongCardUtil.getInstance().toMahjongs(sendCards));
			}
		}
		deskInfo.setGameCurrency(getCurrentyIncome());
		deskInfo.setHMahjongNum(handCards.size());
		deskInfo.addAllHMj(MahjongCardUtil.getInstance().toMahjongs(handCards));
		deskInfo.setTimeout(getWaitTime());
		builder.setGamerDeskInfo(deskInfo.build());
		return builder.build();
	}

	public void reset() {
		isHu = false;
		if (handCards != null) {
			handCards.clear();
		}
		if (group != null) {
			group.clear();
		}
		numberOfSendCard = 0;
		setIsReady(false);
		setHosting(false);
		guoShouHu = null;
		if (incomes != null) {
			incomes.clear();
		}
		if(jings != null) {
			jings.clear();
		}
	}
	
	@Override
	public com.fanrui.proto.cmd.MahjongGamer toCmd() {
		com.fanrui.proto.cmd.MahjongGamer.Builder builder = com.fanrui.proto.cmd.MahjongGamer.newBuilder();
		builder.setUserID(getPlayerID());
		if (playerInfo != null) {
			builder.setNickname(playerInfo.getNickName());
			if(playerInfo.getHeadUrl() == null) {
				builder.setHeadIconUrl("");
			}else {
				builder.setHeadIconUrl(playerInfo.getHeadUrl());
			}
			builder.setUserIP(playerInfo.getIp());
			builder.setLocation(playerInfo.getLocation());
			builder.setLatitudeAndLongitude(playerInfo.getLatitudeAndLongitude());
			builder.setGold(playerInfo.getGold());
			builder.setScore((int) playerInfo.getScore());
			builder.setIsOnline(true);
			builder.setFreestyle("coder");
			builder.setSex(playerInfo.isSex());
		}
		builder.setIsPrepare(isReady());
		builder.setIsHosting(getHosting());
		builder.setIsOnline(getAFK());
		GamerInMahjongDeskInfo.Builder deskInfo = GamerInMahjongDeskInfo.newBuilder();

		if (group != null) {
			deskInfo.addAllMjGroups(group);
		}
		AbstractMahjongTable<?> table = getTable();
		builder.setSeatNo(table.getGamerSeatNO(getPlayerID()));
		if (table.getBankID() != null) {
			deskInfo.setIsBanker(table.getBankID() == getPlayerID());
		}
		if (table != null) {
			Collection<Mahjong> sendCards = table.getSendCards(getPlayerID());
			if (sendCards != null) {
				deskInfo.addAllPopMj(MahjongCardUtil.getInstance().toMahjongs(sendCards));
			}
		}
		deskInfo.setGameCurrency(getCurrentyIncome());
		deskInfo.setHMahjongNum(handCards.size());
		deskInfo.addAllHMj(MahjongCardUtil.getInstance().toMahjongs(handCards));
		deskInfo.setTimeout(getWaitTime());
		builder.setGamerDeskInfo(deskInfo.build());
		return builder.build();
	}

	public boolean canReples() {
		return !replesCard.isEmpty();
	}
	
	public List<Jing> getJings(){
		return jings;
	}
	
	/**
	 * 初始化精牌
	 */
	public void initJing(WannengType type) {
		if(jings == null) {
			jings = new ArrayList<Jing>();
		}
		jings.add(new Jing(type, 0, 0));
	}
	
	/**
	 * 增加精牌
	 */
	public void addJing(WannengType type) {
		if(jings == null) {
			jings = new ArrayList<Jing>();
		}
		if(jings.isEmpty()) {
			jings.add(new Jing(type, 1, 0));
			return;
		}
		for (int i = 0; i < jings.size(); i++) {
			Jing jing = jings.get(i);
			if(type == jing.getType()) {
				jing.setNumber(jing.getNumber()+1);
				jings.set(i, jing);
				return;
			}
		}
	}
	
	public void addGroup(Collection<Mahjong> cards, Operation type) {
		MahjongGroup.Builder builder = MahjongGroup.newBuilder();
		builder.addAllMjs(MahjongCardUtil.getInstance().toMahjongs(cards));
		builder.setType(GroupType.forNumber(type.getNumber()));
		if (group == null) {
			group = new ArrayList<MahjongGroup>();
		}
		group.add(builder.build());
	}
	
	public void addGroup(Mahjong card, Operation type) {
		if (type == Operation.GANG_B) {
			List<MahjongGroup> changed = new ArrayList<MahjongGroup>();
			Iterator<MahjongGroup> iterator = group.iterator();
			while (iterator.hasNext()) {
				MahjongGroup mg = iterator.next();
				if (mg.getType() == GroupType.PENG
						&& card.cardEquals(MahjongCardUtil.getInstance().toMahjongCard(mg.getMjs(0)))) {
					mg = mg.toBuilder().addMjs(card.toCardCmd()).setType(GroupType.GANG_B).build();
					iterator.remove();
					changed.add(mg);
				}

			}
			group.addAll(changed);
		} else {
			addGroup(Arrays.asList(card), type);
		}
	}

	public Collection<Mahjong> removeCard(Mahjong card, int removeNum, boolean mustRemoveAll) {
		return MahjongCardUtil.getInstance().removeCard(handCards, card, removeNum, mustRemoveAll);
	}
	
	public Collection<Mahjong> removeCardCheckId(Mahjong card, int removeNum, boolean mustRemoveAll) {
		return MahjongCardUtil.getInstance().removeCardCheckId(handCards, card, removeNum, mustRemoveAll);
	}
	
	public static Collection<com.fanrui.proto.cmd.MahjongGamer> toGamers(Collection<MahjongGamer> gamers) {
		List<com.fanrui.proto.cmd.MahjongGamer> result = new ArrayList<com.fanrui.proto.cmd.MahjongGamer>();
		if (gamers != null && !gamers.isEmpty()) {
			for (MahjongGamer gamer : gamers) {
				result.add(gamer.toCmd());
			}
		}
		return result;
	}

	@Override
	public void destory() {
		reset();
		ChessGamerManager.getInstance().remove(this);
	}

	/**
	 * 获取玩家在不同类型牌桌的货币
	 * 
	 * @param baseScore
	 * @return
	 */
	public int getRealMoney(int baseScore) {
		CurrencyType type = getTable().getGameRules().getCurrencyType();
		Player player = PlayerDao.getInstance().findById(this.getPlayerID());
		if(player == null) {
			return baseScore;
		}
		if (type == CurrencyType.Score) {
			return baseScore;
		} else if (type == CurrencyType.Gold) {
			if (player.getGold() < baseScore) {
				return (int) player.getGold();
			}
		}
		return baseScore;
	}

	/**
	 * 对某个玩家的金币操作(这里只是对精分的实际分数加减不计入总和)
	 * @param income
	 * @param isGold
	 */
	public synchronized void addIncomeBuyOne(MahjongIncome income) {
		// 金币场及时结算
		if (getTable() != null && getTable().getGameRules().getCurrencyType() == CurrencyType.Gold) {
			long gold = income.getIncome();
			Player thisPlayer = PlayerManager.getInstance().findOrCreatePlayer(income.getScoure());
			if(thisPlayer == null) {
				return;
			}
			// 增加的金币不能超过拥有的金币
			if(gold < 0) {
				gold = -gold;
				gold = gold > thisPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
						? thisPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
						: gold;
				thisPlayer.operationCost(com.fanrui.proto.cmd.CurrencyType.C_Gold, gold, OperationType.Minus);
			}else {
				gold = gold > thisPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
						? thisPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
						: gold;
				thisPlayer.operationCost(com.fanrui.proto.cmd.CurrencyType.C_Gold, gold, OperationType.Add);
			}
		}
		addIncome(income.getIncome());
	}
	
	public synchronized void addIncome(MahjongIncome income) {
		if (incomes == null) {
			incomes = new ArrayList<MahjongIncome>();
		}
		incomes.add(income);
		// 金币场及时结算
		if (getTable() != null && getTable().getGameRules().getCurrencyType() == CurrencyType.Gold) {
			if (income.getIncome() > 0) {
				for (MahjongIncomeInfo mahjongIncomeInfo : income.getSelated()) {
					// 对方信息
					long gold = mahjongIncomeInfo.getIncome();
					long otherPlayerID = mahjongIncomeInfo.getPlayerId();
					Player otherPlayer = PlayerManager.getInstance().findOrCreatePlayer(otherPlayerID);
					Player thisPlayer = PlayerManager.getInstance().findOrCreatePlayer(income.getScoure());
					Stdout.GET().info(otherPlayerID + "输给了" + income.getScoure() + "，【" + gold + "】金币");
					// 根据玩家身上的金币数量 和抽水（系统抽水 和 家族抽水）情况得出最终的收益
					// otherPlayer金币减少，thisPlayer金币增加

					// TODO 要整理一下
					if (otherPlayer != null && thisPlayer != null) {

						/** otherPlayer金币减少 **/
						// 玩家金币不足
						gold = gold > otherPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
								? otherPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
								: gold;
						otherPlayer.operationCost(com.fanrui.proto.cmd.CurrencyType.C_Gold, gold, OperationType.Minus);
						/** thisPlayer金币增加 **/
						// 增加的金币不能超过拥有的金币
						gold = gold > thisPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
								? thisPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
								: gold;
						thisPlayer.operationCost(com.fanrui.proto.cmd.CurrencyType.C_Gold, gold, OperationType.Add);

					} else if (otherPlayer != null && thisPlayer == null) {
						/** otherPlayer金币减少 **/
						// 玩家金币不足
						gold = gold > otherPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
								? otherPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
								: gold;
						otherPlayer.operationCost(com.fanrui.proto.cmd.CurrencyType.C_Gold, gold, OperationType.Minus);

						MahjongGamer thisGamer = getTable().getGamerByPlayerID(getPlayerID());
						gold = gold > thisGamer.getPlayerInfo().getGold() ? thisGamer.getPlayerInfo().getGold() : gold;
						thisGamer.getPlayerInfo().setGold(thisGamer.getPlayerInfo().getGold() + gold);
					} else if (otherPlayer == null && thisPlayer != null) {
						// 机器人
						MahjongGamer otherGamer = getTable().getGamerByPlayerID(otherPlayerID);
						gold = gold > otherGamer.getPlayerInfo().getGold() ? otherGamer.getPlayerInfo().getGold()
								: gold;
						otherGamer.getPlayerInfo().setGold(otherGamer.getPlayerInfo().getGold() - gold);

						/** thisPlayer金币增加 **/
						// 增加的金币不能超过拥有的金币
						gold = gold > thisPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
								? thisPlayer.getCurrencyValue(com.fanrui.proto.cmd.CurrencyType.C_Gold)
								: gold;
						thisPlayer.operationCost(com.fanrui.proto.cmd.CurrencyType.C_Gold, gold, OperationType.Add);
					} else {
						// 机器人
						MahjongGamer otherGamer = getTable().getGamerByPlayerID(otherPlayerID);
						gold = gold > otherGamer.getPlayerInfo().getGold() ? otherGamer.getPlayerInfo().getGold()
								: gold;
						otherGamer.getPlayerInfo().setGold(otherGamer.getPlayerInfo().getGold() - gold);
						MahjongGamer thisGamer = getTable().getGamerByPlayerID(getPlayerID());
						gold = gold > thisGamer.getPlayerInfo().getGold() ? thisGamer.getPlayerInfo().getGold() : gold;
						thisGamer.getPlayerInfo().setGold(thisGamer.getPlayerInfo().getGold() + gold);
					}
				}
			}
		}
		addIncome(income.getIncome());
	}
	
	public boolean addIncome(int val) {
		this.income.addAndGet(val);
		return false;
	}
	
	public boolean notSend() {
		return numberOfSendCard == 0;
	}
	
	public Collection<Mahjong> getHandlCard() {
		return handCards;
	}
}
